Array.prototype.MyReduce = function (callback, initialValue) {
    // thisArg 执行 callback 时，用于 this 的值。
    // console.log(this)
    if (this == undefined) { // this是调用的Array，如果没有直接报错
        throw new TypeError('this is null or not undefined');
    }
    if (typeof callback !== 'function') { // 如果回调不是函数报错
        throw new TypeError(callback + 'is not a function')
    }

    const O = Object(this);
    let len = O.length;
    ;
    let k = 0;


    //  // 如果第二个参数为undefined的情况下
    // 则数组的第一个有效值作为累加器的初始值
    if (initialValue === undefined) {  // 如果不传入initialValue，则以数组第0位为初始值

        while (k < len && !(k in O)) {
            // k < len 且  k 不属于O 小标 不好理解
            k++;
        }

        // 个人理解： 可以直接 k++ , 因为不传initialValue值，默认将Array[0]作为初始值，因此要从Array[1]开始进行累加

        // 如果超出数组界限还没有找到累加器的初始值，则TypeError
        if (k >= len) {
            throw new TypeError('Reduce of empty array with no initial value');
        }
        accumulator = O[k++];
    }

    while (k < len) {
        if (k in O) {
            accumulator = callback.call(undefined, accumulator, O[k], k, O);  // accumulator 将最终结果传回最为第二个参数，第一个参数为call的指针。
        }
        k++;
    }
    return accumulator;
}


let array = [1, 2, 3, 4, 5];
const sumWithInitial = array.reduce(
    (previousValue, currentValue, i, z) => {
        console.log(i);
        console.log(z);
        return previousValue + currentValue
    }
    
);